package libra.sentinelRestTemplate;

import java.io.IOException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.ResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

import com.alibaba.cloud.sentinel.annotation.SentinelRestTemplate;

import libra.sentinelRestTemplate.call.BlockExHandler_RestTemplate;

/**
 * 针对RestTemplate的配置类
 * @author libra
 */
@Configuration
public class RestTemplateConfig {
	/*
	 * 如果当前应用属于'服务消费者'，需要调用其他服务的接口功能
	 * 则需要在RestTemplate的bean定义上使用@LoadBalanced进行标注，开启客户端的负载均衡
	 * 否则在服务调用时，会因无法解析服务名而抛出UnknownHostException异常 
	 */
	@LoadBalanced
	@Bean
	@SentinelRestTemplate(
	    blockHandler = "handleException", blockHandlerClass = BlockExHandler_RestTemplate.class,
	    fallback = "handleFallback",fallbackClass = BlockExHandler_RestTemplate.class
	)
	public RestTemplate serviceSentinelRestTemplate(
		@Autowired SimpleClientHttpRequestFactory clientHttpRequestFactory, @Autowired ResponseErrorHandler respErrorHandler 
	){
	    RestTemplate restTemplate = new RestTemplate();
	    restTemplate.setRequestFactory(clientHttpRequestFactory);
	    restTemplate.setErrorHandler( respErrorHandler );
		return restTemplate;
	}
	
	@Bean
	@SentinelRestTemplate(
	    blockHandler = "handleException", blockHandlerClass = BlockExHandler_RestTemplate.class,
	    fallback = "handleFallback",fallbackClass = BlockExHandler_RestTemplate.class
	)
	public RestTemplate localSentinelRestTemplate( 
		@Autowired SimpleClientHttpRequestFactory clientHttpRequestFactory, @Autowired ResponseErrorHandler respErrorHandler 
	){
	    RestTemplate restTemplate = new RestTemplate();
	    restTemplate.setRequestFactory( clientHttpRequestFactory );
	    restTemplate.setErrorHandler( respErrorHandler );
		return restTemplate;
	}
	
	@Bean
	public SimpleClientHttpRequestFactory clientHttpRequestFactory() {
		//配置http请求的连接超时时间和读取超时时间
		SimpleClientHttpRequestFactory clientHttpRequestFactory = new SimpleClientHttpRequestFactory();
	    clientHttpRequestFactory.setConnectTimeout(5000);
	    clientHttpRequestFactory.setReadTimeout(5000);
	    return clientHttpRequestFactory;
	}
	@Bean
    public ResponseErrorHandler respErrorHandler() {
    	return new SelfResponseErrorHandler();
    }
}
// DefaultResponseErrorHandler：RestTemplate底层默认使用的异常处理器
class SelfResponseErrorHandler extends DefaultResponseErrorHandler {
	// 通过状态码判断HttpResponse是否是异常响应
	@Override
	public boolean hasError(ClientHttpResponse response) throws IOException {
		return super.hasError(response);
	}
	// 用于处理异常响应结果(非200状态码段)
	@Override
	public void handleError(ClientHttpResponse response) throws IOException {
		// 如果是自定义状态码439(限流)/449(熔断)，则视为Response直接返回；否则则视为异常，交由底层默认处理；
		if( response.getRawStatusCode() != 439 && response.getRawStatusCode() != 449   ) {
			super.handleError(response);
//			throw new RestClientResponseException("11", response.getRawStatusCode(), "22", response.getHeaders(), getResponseBody(response), getCharset(response));
		}
	}
}
